package com.hq.ims.data.service.other;

import com.alibaba.fastjson.JSONObject;
import com.hq.ims.data.utils.ImageUtil;
import com.hq.ims.data.vo.ocr.AliCardOcrVo;
import com.hq.ims.data.vo.ocr.OcrFaceRectVo;
import com.hq.ims.data.vo.ocr.OcrSizeVo;
import com.hq.ims.data.vo.ocr.OcrXyVo;
import com.hq.utils.util.JsonUtils;
import com.hq.web.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * lichaojie
 *
 * @ClassName AliOrcUtil
 **/
@Slf4j
@Service
public class AliOcrBusService {

    @Value("${userAttribute.ali.aliOcrUrl}")
    public String aliOcrUrl;

    @Value("${userAttribute.ali.aliOcrAppCoed}")
    public String aliOcrAppCoed;

    @Resource
    private ImageUtil imageUtil;

    public AliCardOcrVo httpCardOrc(String filePath) {
        // 对图像进行base64编码
        String imgBase64 = imgBase64(filePath);

        return httpCardOrcByBase64(imgBase64);
    }

    public AliCardOcrVo httpCardOrcByBase64(String base64) {
        // 对图像进行base64编码
        log.info("参数组装前》》》》" + System.currentTimeMillis());
        HashMap<String, Object> params = new HashMap<>();
        params.put("image", base64);
        //configure配置
        JSONObject configObj = new JSONObject();
        configObj.put("side", "face");
        params.put("configure", configObj.toString());

        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + aliOcrAppCoed);
        log.info("参数组装后》》》》" + System.currentTimeMillis());

        log.info("方法执行前》》》》" + System.currentTimeMillis());
        Map map = HttpUtils.postJson(aliOcrUrl, params, headers, 5);
        log.info("方法执行后》》》》" + System.currentTimeMillis());

        if (map == null) {
            log.error("<<<<<<<<身份识别失败");
        }
        return JsonUtils.convertObject(map, AliCardOcrVo.class);
    }

    /**
     * @param aliCardOcrVo
     * @return : com.hq.ce.safety.data.vo.ocr.AliCardOcrVo
     * <p>
     * <p>
     * 获取身份证头像
     */
    public MultipartFile getIdCardAvatar(MultipartFile file, AliCardOcrVo aliCardOcrVo) throws IOException {
        if (aliCardOcrVo == null) {
            return null;
        }
        OcrFaceRectVo face_rect = aliCardOcrVo.getFace_rect();
        if (face_rect == null) {
            return null;
        }
        OcrSizeVo size = face_rect.getSize();
        if (size == null) {
            return null;
        }
        List<OcrXyVo> face_rect_vertices = aliCardOcrVo.getFace_rect_vertices();
        if (face_rect_vertices == null) {
            return null;
        }
        OcrXyVo ocrXyVo;

        int x;
        int y;
        int width;
        int height;

        Integer angle = face_rect.getAngle();
        if ((angle >= 0 && angle <= 30) || (angle >= 330)) {
            ocrXyVo = face_rect_vertices.get(2);
            x = ocrXyVo.getX();
            y = ocrXyVo.getY();
            width = size.getHeight();
            height = size.getWidth();
        } else if (angle >= 60 && angle <= 120) {
            ocrXyVo = face_rect_vertices.get(1);
            x = ocrXyVo.getX();
            y = ocrXyVo.getY();
            width = size.getWidth();
            height = size.getHeight();
        } else if (angle >= 150 && angle <= 210) {
            ocrXyVo = face_rect_vertices.get(0);
            x = ocrXyVo.getX();
            y = ocrXyVo.getY();
            width = size.getWidth();
            height = size.getHeight();
        } else if (angle >= 240 && angle <= 300) {
            ocrXyVo = face_rect_vertices.get(3);
            x = ocrXyVo.getX();
            y = ocrXyVo.getY();
            width = size.getHeight();
            height = size.getWidth();
        } else {
            return null;
        }
        //截取身份证头像
        return imageUtil.cropImage(file, x, y, width, height, angle);
    }

    private String imgBase64(String path) {
        /**
         *  对path进行判断，如果是本地文件就二进制读取并base64编码，如果是url,则返回
         */
        String imgBase64 = "";
        if (path.startsWith("http")) {
            imgBase64 = path;
        } else {
            try {
                File file = new File(path);
                byte[] content = new byte[(int) file.length()];
                FileInputStream finputstream = new FileInputStream(file);
                finputstream.read(content);
                finputstream.close();
                imgBase64 = new String(Base64.encodeBase64(content));
            } catch (IOException e) {
                e.printStackTrace();
                return imgBase64;
            }
        }
        return imgBase64;
    }


    /**
     * 得到身份证照片
     *
     * @param file         多部分文件
     * @param aliCardOrcVo 阿里卡兽人返回对象
     * @return {@code MultipartFile }
     */
    public MultipartFile getIdCardPhoto(MultipartFile file, AliCardOcrVo aliCardOrcVo) throws IOException {
        if (aliCardOrcVo == null) {
            return null;
        }
        OcrFaceRectVo face_rect = aliCardOrcVo.getFace_rect();
        if (face_rect == null) {
            return null;
        }
        OcrSizeVo size = face_rect.getSize();
        if (size == null) {
            return null;
        }
        List<OcrXyVo> card_region = aliCardOrcVo.getCard_region();
        if (card_region == null) {
            return null;
        }
        OcrXyVo ocrXyVo_1 = card_region.get(0);
        OcrXyVo ocrXyVo_3 = card_region.get(2);

        //身份证左上角顶点就是第一顶点
        int x = ocrXyVo_1.getX();
        int y = ocrXyVo_1.getY();
        //坐标相减计算宽高
        int width = ocrXyVo_3.getX() - ocrXyVo_1.getX();
        int height = ocrXyVo_3.getY() - ocrXyVo_1.getY();

        Integer angle = face_rect.getAngle();

        //截取身份证头像
        return imageUtil.cropImage(file, x, y, width, height, angle);
    }
}
